#ifndef __CARD_H_
#define __CARD_H_
// Includes
#include <avr/io.h>
#include <stdbool.h>

// ============================== Timings ======================================
#define CRD_RETRY_TIMEOUT   496  // ms
#define CRD_REPLY_TIMEOUT   4005  // ms

// =============================== Variables ===================================
enum CardState_t{ csCardOut, csCardOk, csCardError };
enum Type_t { ctUndefined, ctMifareMini, ctMifareClassic1K, ctMifareClassic4K, ctMifareUltralight, ctMifareDESFire, ctInfineonMifareClassic1K, ctJCOP };

class Card_t {
private:
    uint16_t Timer;
public:
    bool IsMifare;
    CardState_t State;
    // ATR section
    uint8_t ATR[36], AtrLength;    // Buffer to store ATR
    uint8_t *Data;
    uint16_t DataLength;
    Type_t Type;
    //void Init(void) { State = csCardOut; IsMifare = false; }
    void DetermineType(void);
    void ConstructATR(void);
    void MetroInfoDescrypted(uint8_t *MemBuf);
};

extern Card_t Card;

class MetroInfo_t {
public:
    uint8_t MemoryBuf[64];
    bool DecryptComplete;
    uint16_t AppID; // Started at 16 (<<8 >>6)
    uint16_t *PAppID;
    uint16_t Cardtype; // Started at 18 (<<8 >>4)
    uint16_t *PCardType;
    uint32_t TcktNmb;
    uint32_t *PTcktNmb;
    uint8_t Layout; // Started at 22
    uint8_t *PLayout;
    uint16_t BlankbestBefore; // Started at 23 (<<8)
    uint16_t *PBlankBestBefore;
    uint16_t Issued; // 32 33
    uint16_t *PIssued;
    uint8_t BestInDays; // 34
    uint8_t *PBestInDays;
    uint16_t PassesLeft; // 36 37
    uint16_t * PPassesLeft;
    uint16_t StationLastEnter; // 38 39
    uint16_t *PStationLastEnter;
    uint32_t HASH; // 40 41 42 43
    uint32_t * PHASH;
};

extern MetroInfo_t Metro;
#endif
